import pandas as pd
from gofishing.base import Base
from gofishing.broker import Broker


class ObserverBase:

    observers: dict[str, 'ObserverBase'] = {}

    def __init__(self, observerID: str) -> None:
        if observerID in ObserverBase.observers:
            raise Exception('observerID must be unique')
        else:
            self.observerID = observerID
            ObserverBase.observers[self.observerID] = self

    def updateRecord(self) -> None:
        raise NotImplementedError

    def update() -> None:
        observers = ObserverBase.observers
        for observerID in observers:
            observers[observerID].updateRecord()

    def composeRecord(self) -> pd.DataFrame:
        raise NotImplementedError


class AccountObserver(ObserverBase):

    def __init__(self, observerID: str, recordIndex: pd.DatetimeIndex) -> None:
        super().__init__(observerID=observerID)
        self.record = []
        self.recordIndex = recordIndex

    def updateRecord(self) -> None:
        now = Base.now()
        if now in self.recordIndex:
            self._addRecord()

    def _addRecord(self) -> None:
        now = Base.now()
        accountValues = Broker.getAccountValues()
        rowData = [now,
                   accountValues.staticValue,
                   accountValues.frozenMargin,
                   accountValues.frozenCommission,
                   accountValues.floatingProfit,
                   accountValues.value,
                   accountValues.margin,
                   accountValues.available,
                   accountValues.riskRatio]
        self.record.append(rowData)

    def composeRecord(self) -> pd.DataFrame:
        columns = ['time', 'staticValue', 'frozenMargin', 'frozenCommission',
                   'floatingProfit', 'value', 'margin', 'available',
                   'riskRatio']
        return pd.DataFrame(data=self.record, columns=columns)
